From 36453a8a6bad2c814a4e554182c51793969e24be Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Wed, 2 Jul 2014 17:55:20 -0400 Subject: [PATCH] GktAdjustment: Add explicit api for animated setting Making all set_value calls animated has side-effects, so we need to be more selective. --- gtk/gtkadjustment.c | 110 +++++++++++++++++++++---------------- gtk/gtkadjustmentprivate.h | 2 + 2 files changed, 65 insertions(+), 47 deletions(-) diff --git a/gtk/gtkadjustment.c b/gtk/gtkadjustment.c index a124bac471..8cab120dc2 100644 --- a/gtk/gtkadjustment.c +++ b/gtk/gtkadjustment.c @@ -432,13 +432,42 @@ static void adjustment_set_value (GtkAdjustment *adjustment, gdouble value) { - if (value != adjustment->priv->value) + if (adjustment->priv->value != value) { adjustment->priv->value = value; gtk_adjustment_value_changed (adjustment); } } +static void gtk_adjustment_on_frame_clock_update (GdkFrameClock *clock, + GtkAdjustment *adjustment); + +static void +gtk_adjustment_begin_updating (GtkAdjustment *adjustment) +{ + GtkAdjustmentPrivate *priv = adjustment->priv; + + if (priv->tick_id == 0) + { + priv->tick_id = g_signal_connect (priv->clock, "update", + G_CALLBACK (gtk_adjustment_on_frame_clock_update), adjustment); + gdk_frame_clock_begin_updating (priv->clock); + } +} + +static void +gtk_adjustment_end_updating (GtkAdjustment *adjustment) +{ + GtkAdjustmentPrivate *priv = adjustment->priv; + + if (priv->tick_id != 0) + { + g_signal_handler_disconnect (priv->clock, priv->tick_id); + priv->tick_id = 0; + gdk_frame_clock_end_updating (priv->clock); + } +} + /* From clutter-easing.c, based on Robert Penner's * infamous easing equations, MIT license. */ @@ -450,11 +479,14 @@ ease_out_cubic (gdouble t) return p * p * p + 1; } -static gboolean -gtk_adjustment_animate_step (GtkAdjustment *adjustment, - gint64 now) +static void +gtk_adjustment_on_frame_clock_update (GdkFrameClock *clock, + GtkAdjustment *adjustment) { GtkAdjustmentPrivate *priv = adjustment->priv; + gint64 now; + + now = gdk_frame_clock_get_frame_time (clock); if (now < priv->end_time) { @@ -463,58 +495,43 @@ gtk_adjustment_animate_step (GtkAdjustment *adjustment, t = (now - priv->start_time) / (gdouble) (priv->end_time - priv->start_time); t = ease_out_cubic (t); adjustment_set_value (adjustment, priv->source + t * (priv->target - priv->source)); - - return TRUE; } else { adjustment_set_value (adjustment, priv->target); - - return FALSE; - } -} - -static void -gtk_adjustment_on_frame_clock_update (GdkFrameClock *clock, - GtkAdjustment *adjustment) -{ - GtkAdjustmentPrivate *priv = adjustment->priv; - gint64 now; - - now = gdk_frame_clock_get_frame_time (clock); - if (!gtk_adjustment_animate_step (adjustment, now)) - { - g_signal_handler_disconnect (priv->clock, priv->tick_id); - priv->tick_id = 0; - gdk_frame_clock_end_updating (priv->clock); + gtk_adjustment_end_updating (adjustment); } } static void -gtk_adjustment_maybe_animate (GtkAdjustment *adjustment, - gdouble target) +gtk_adjustment_set_value_internal (GtkAdjustment *adjustment, + gdouble value, + gboolean animate) { GtkAdjustmentPrivate *priv = adjustment->priv; - if (priv->target == target) - return; + /* don't use CLAMP() so we don't end up below lower if upper - page_size + * is smaller than lower + */ + value = MIN (value, priv->upper - priv->page_size); + value = MAX (value, priv->lower); - priv->target = target; - - if (priv->duration != 0 && priv->clock != NULL) + if (animate && priv->duration != 0 && priv->clock != NULL) { + if (priv->target == value) + return; + priv->source = priv->value; + priv->target = value; priv->start_time = gdk_frame_clock_get_frame_time (priv->clock); priv->end_time = priv->start_time + 1000 * priv->duration; - if (priv->tick_id == 0) - { - priv->tick_id = g_signal_connect (priv->clock, "update", - G_CALLBACK (gtk_adjustment_on_frame_clock_update), adjustment); - gdk_frame_clock_begin_updating (priv->clock); - } + gtk_adjustment_begin_updating (adjustment); } else - adjustment_set_value (adjustment, target); + { + gtk_adjustment_end_updating (adjustment); + adjustment_set_value (adjustment, value); + } } /** @@ -533,19 +550,18 @@ void gtk_adjustment_set_value (GtkAdjustment *adjustment, gdouble value) { - GtkAdjustmentPrivate *priv; - g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - priv = adjustment->priv; + gtk_adjustment_set_value_internal (adjustment, value, FALSE); +} - /* don't use CLAMP() so we don't end up below lower if upper - page_size - * is smaller than lower - */ - value = MIN (value, priv->upper - priv->page_size); - value = MAX (value, priv->lower); +void +gtk_adjustment_animate_to_value (GtkAdjustment *adjustment, + gdouble value) +{ + g_return_if_fail (GTK_IS_ADJUSTMENT (adjustment)); - gtk_adjustment_maybe_animate (adjustment, value); + gtk_adjustment_set_value_internal (adjustment, value, TRUE); } /** diff --git a/gtk/gtkadjustmentprivate.h b/gtk/gtkadjustmentprivate.h index bc9c810152..b36f13fa75 100644 --- a/gtk/gtkadjustmentprivate.h +++ b/gtk/gtkadjustmentprivate.h @@ -27,6 +27,8 @@ G_BEGIN_DECLS void gtk_adjustment_enable_animation (GtkAdjustment *adjustment, GdkFrameClock *clock, guint duration); +void gtk_adjustment_animate_to_value (GtkAdjustment *adjustment, + gdouble value); G_END_DECLS -- 2.30.2